﻿using Omniscient.Foundation;
using Omniscient.Foundation.ApplicationModel.Modularity;
using Omniscient.Foundation.ApplicationModel.Presentation;
using Omniscient.Foundation.Data;
using Omniscient.TimeTracker.Data;
using Omniscient.TimeTracker.Presentation;
using Omniscient.Foundation.ApplicationModel;
using System.Collections.Generic;
using System;

namespace Omniscient.TimeTracker.TaskBarMenu
{
    public class TaskBarMenuModule : IModule, IStartable
    {
        #region IModule Members

        public IPresentationController PresentationController { get; set; }

        #endregion

        #region IStartable Members

        public void Start()
        {
            // Get port manager
            IExtensionPortManager manager;
            manager = ApplicationManager.Current.ExtensionPortManager;
            // Get port
            IExtensionPort<IViewControllerExtenderContract> port;
            port = manager.GetExtensionPort<IViewControllerExtenderContract>();

            if (port != null)
            {
                TaskBarMenuViewControllerExtender extender;
                extender = new TaskBarMenuViewControllerExtender();
                // Register the extender for the port
                port.Register(extender);
            }

            EntityList<Client> clients = GetClients();
            EntityList<Category> categories = GetCategories();

            TaskBarMenuModel model;
            model = new TaskBarMenuModel(clients, categories);
            
            PresentationController.OpenView(model);
        }

        public void Stop()
        {
        }

        #endregion

        private EntityList<Client> GetClients()
        {
            //todo: refactor this code using different IComposer classes
            IEntityAdapter<Task> taskAdapter;
            IEntityAdapter<Project> projectAdapter;
            IEntityAdapter<Client> clientAdapter;

            taskAdapter = ApplicationManager.Current.ServiceProvider.GetService<IEntityAdapter<Task>>();
            projectAdapter = ApplicationManager.Current.ServiceProvider.GetService<IEntityAdapter<Project>>();
            clientAdapter = ApplicationManager.Current.ServiceProvider.GetService<IEntityAdapter<Client>>();

            if (taskAdapter == null || projectAdapter == null || clientAdapter == null)
            {
                return null;
            }

            EntityList<Task> taskList = taskAdapter.LoadAll();
            EntityList<Project> projectList = projectAdapter.LoadAll();
            EntityList<Client> clientList = clientAdapter.LoadAll();

            // Should be included in ClientComposer
            Dictionary<Guid, Client> clientDictionary;
            clientDictionary = new Dictionary<Guid, Client>();
            foreach (Client c in clientList)
            {
                clientDictionary.Add(c.Id, c);
            }

            // Should be included in ProjectComposer
            Dictionary<Guid, Project> projectDictionary;
            projectDictionary = new Dictionary<Guid, Project>();
            foreach (Project p in projectList)
            {
                projectDictionary.Add(p.Id, p);
            }

            // Should be included in ProjectComposer
            foreach (Task t in taskList)
            {
                Guid foreignKey = t.ParentProject.Id;

                if (projectDictionary.ContainsKey(foreignKey))
                {
                    t.ParentProject = projectDictionary[foreignKey];
                    projectDictionary[foreignKey].Tasks.Add(t);
                }
            }

            // Should be included in ClientComposer
            foreach (Project p in projectList)
            {
                Guid foreignKey = p.ParentClient.Id;

                if (clientDictionary.ContainsKey(foreignKey))
                {
                    p.ParentClient = clientDictionary[foreignKey];
                    clientDictionary[foreignKey].Projects.Add(p);
                }
            }

            // Should be included in ClientComposer
            EntityList<Client> result = new EntityList<Client>();
            foreach (Client client in clientDictionary.Values)
            {
                result.Add(client);
            }
            return result;
        }

        private EntityList<Category> GetCategories()
        {
            IEntityAdapter<Category> categoryAdapter;
            categoryAdapter = ApplicationManager.Current.ServiceProvider.GetService<IEntityAdapter<Category>>();

            if (categoryAdapter != null)
            {
                return categoryAdapter.LoadAll();
            }
            return null;
        }
    }
}
